using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using NCT.Framework;
using NCT.Framework.Database;
using VISS.API.CustomUtils;

namespace VISS.API.Users {

    class UserBC : IUser, IUserAdmin {

        #region IUser Members

        public bool Insert(UserEnt item, UserGeneralProfileEnt pItem, UserContactInfoEnt cItem) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Create UserKey for user
                string userKey;
                if (!CreateUserKey(out userKey))
                    return false;
                item.UserKey = userKey;

                //Random Password for user
                string password;
                if (!RandomPassword(out password))
                    return false;
                item.Password = password;

                //Encrypt password
                item.Password = StringUtils.DoMD5(item.Password);

                //Normalize data
                if (item.DateCreated <= DateTimeUtils.MinValue) {
                    item.DateCreated = DateTime.Now;
                }
                item.DateModified = DateTime.Now;
                item.Status = EUserStatus.NotActived;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Add User to DB
                result = UserDA.Insert(item, connectionName, dbCon, dbTrans) > 0;

                if(!result) return result;

                item.Password = password;

                //Add log
                if (result) {
                }

                //Create new UserGeneralProfileEnt if not existed
                if (pItem == null) {
                    pItem = new UserGeneralProfileEnt();
                }

                pItem.UserKey = item.UserKey;

                //Normalize data
                pItem.Name = StringUtils.Normalize(pItem.Name);
                if (pItem.DateModified <= DateTimeUtils.MinValue) {
                    pItem.DateModified = DateTime.Now;
                }

                // Add UserGeneralProfile to DB
                if (result) {
                    result = UserGeneralProfileDA.Insert(pItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Create UserContactInfoEnt 
                if (cItem == null) {
                    cItem = new UserContactInfoEnt();
                }

                // Set value for UserContactInfoEnt
                cItem.UserKey = pItem.UserKey;
                cItem.Email = item.Email;
                cItem.CityID = pItem.CityID;
                cItem.CountryID = pItem.CountryID;
                if (cItem.DateModified <= DateTimeUtils.MinValue) {
                    cItem.DateModified = DateTime.Now;
                }

                // Add UserContactInfoEnt to DB
                if (result) {
                    result = UserContactInfoDA.Insert(cItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Create UserApperanceProfileEnt 
                UserApperanceProfileEnt aItem = new UserApperanceProfileEnt();
                aItem.UserKey = item.UserKey;
                aItem.DateCreated = DateTime.Now;

                // Add UserApperanceProfileEnt to DB
                if (result) {
                    result = UserAppearanceProfileDA.Insert(aItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Create UserCultureProfileEnt
                UserCultureProfileEnt cuItem = new UserCultureProfileEnt();
                cuItem.UserKey = item.UserKey;
                cuItem.DateCreated = DateTime.Now;

                // Add UserCultureProfileEnt to DB
                if (result) {
                    result = UserCultureProfileDA.Insert(cuItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Create UserFamilyProfileEnt
                UserFamilyProfileEnt fItem = new UserFamilyProfileEnt();
                fItem.UserKey = item.UserKey;
                fItem.DateCreated = DateTime.Now;

                // Add UserFamilyProfileEnt to DB
                if (result) {
                    result = UserFamilyProfileDA.Insert(fItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Create UserLivingProfileEnt
                UserLivingProfileEnt lItem = new UserLivingProfileEnt();
                lItem.UserKey = item.UserKey;
                lItem.DateCreated = DateTime.Now;

                // Add UserLivingProfileEnt to DB
                if (result) {
                    result = UserLivingProfileDA.Insert(lItem, connectionName, dbCon, dbTrans) > 0;
                }

                if (!result) return result;

                //Add log
                if (result) {
                }

                // Add User into Cache
                if (result && ConfigInfo.UseCache) {

                    // Add UserGeneralProfile into Cache
                    if (result) {
                    }

                    // Add UserContactInfoEnt into Cache
                    if (result) {
                    }

                    // Add UserApperanceProfileEnt into Cache
                    if (result) {
                    }

                    // Add UserCultureProfileEnt into Cache
                    if (result) {
                    }

                    // Add UserFamilyProfileEnt into Cache
                    if (result) {
                    }

                    // Add UserLivingProfileEnt into Cache
                    if (result) {
                    }
                }
            }
            catch (Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.Insert({0}, {1}, {2}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item),
                                    SerializerUtils.JsonSerialize(pItem),
                                    SerializerUtils.JsonSerialize(cItem)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateEmail(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdateEmail(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdateEmail({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateEmail(string userKey, string email) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.Email = email;

            return UpdateEmail(item);
        }

        public bool UpdatePassword(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {

                //Encrypt password
                item.Password = StringUtils.DoMD5(item.Password);

                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdatePassword(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdatePassword({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdatePassword(string userKey, string password) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.Password = password;

            return UpdatePassword(item);
        }

        public bool UpdateSLink(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdateSLink(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdateSLink({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateSLink(string userKey, string sLink) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.SLink = sLink;

            return UpdateSLink(item);
        }

        public bool UpdateSLinkExpiredDate(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdateSLinkExpiredDate(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdateSLinkExpiredDate({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateSLinkExpiredDate(string userKey, DateTime sLinkExpiredDate) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.SLinkExpiredDate = sLinkExpiredDate;

            return UpdateSLinkExpiredDate(item);
        }

        public bool UpdateSLinkAndSLinkExpiredDate(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdateSLink_SLinkExpiredDate(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdateSLink_SLinkExpiredDate({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateSLinkAndSLinkExpiredDate(string userKey, string sLink, DateTime sLinkExpiredDate) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.SLink = sLink;
            item.SLinkExpiredDate = sLinkExpiredDate;

            return UpdateSLinkAndSLinkExpiredDate(item);
        }

        public bool UpdateStatus(UserEnt item) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                if (item.DateModified <= DateTimeUtils.MinValue) {
                    item.DateModified = DateTime.Now;
                }

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.UpdateStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UpdateStatus({0}, {1}): \n" + ex.ToString(),
                                    SerializerUtils.JsonSerialize(item)));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UpdateStatus(string userKey, EUserStatus status) {
            UserEnt item = new UserEnt();
            item.UserKey = userKey;
            item.Status = status;

            return UpdateStatus(item);
        }

        public UserEnt GetByUserKey(string userKey) {
            UserEnt item = null;
            try {
                if (ConfigInfo.UseCache) {
                }
                else {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    item = UserDA.GetByUserKey(userKey, connectionName, null, null);
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.GetByUserKey({0}): \n" + ex.ToString(), userKey));
            }
            return item;
        }
        public UserEnt GetUserByEmail(string email)
        {
            UserEnt item = null;
            try
            {
                if (ConfigInfo.UseCache)
                {
                }
                else
                {
                    //Get connection name
                    string connectionName = ConfigInfo.ConnectionName;

                    item = UserDA.GetByEmail(email, connectionName, null, null);
                }
            }

            catch (System.Exception ex)
            {
                LogUtils.Error(string.Format("VISS.Users.UserBC.GetByUserKey({0}): \n" + ex.ToString(), email));
            }
            return item;
        }

        public bool ResetPassword(string userKey, out string password) {
            password = string.Empty;
            bool result = true;

            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();
                item.UserKey = userKey;

                if (!RandomPassword(out password))
                    return false;

                item.Password = password;

                //Encrypt password
                item.Password = StringUtils.DoMD5(item.Password);

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                result = UserDA.UpdatePassword(item, connectionName, dbCon, dbTrans) > 0;

                // Add log
                if (result) {
                }

                // Update user to Cache
                if (result) {
                }

            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.ResetPassword({0}): \n" + ex.ToString(), userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public EUserLoginResult Login(string email, string password, out UserEnt item) {
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                password = StringUtils.DoMD5(password);

                if (ConfigInfo.UseCache) {
                    item = null;
                }
                else {
                    item = UserDA.GetByEmail(email, connectionName, null, null);
                }

                if (item == null) {
                    return EUserLoginResult.WrongEmail;
                }

                if (item.Password != password) {
                    return EUserLoginResult.WrongPassword;
                }

                if ((item.Status & EUserStatus.Deleted) != 0) {
                    return EUserLoginResult.Deleted;
                }

                if ((item.Status & EUserStatus.Disabled) != 0) {
                    return EUserLoginResult.Disabled;
                }                

                if (item.Status == EUserStatus.NotActived) {
                    item.DateActivated = DateTime.Now;
                    UserDA.ActiveAccount(item, connectionName, null, null);

                    if (ConfigInfo.UseCache) {
                    }
                }

                item.LastLogin = DateTime.Now;
                UserDA.UpdateLastLogin(item, connectionName, null, null);

                // Update User into Cache
                if (ConfigInfo.UseCache) {
                }

                return EUserLoginResult.Success;
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.Login({0}): \n" + ex.ToString(), email));
                item = null;
                return EUserLoginResult.Unknown;
            }
        }

        public EUserLoginResult OpenIDLogin(string email, out UserEnt item) {
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                if (ConfigInfo.UseCache) {
                    item = null;
                }
                else {
                    item = UserDA.GetByEmail(email, connectionName, null, null);
                }

                if (item == null) {
                    return EUserLoginResult.WrongEmail;
                }

                if ((item.Status & EUserStatus.Deleted) != 0) {
                    return EUserLoginResult.Deleted;
                }

                if ((item.Status & EUserStatus.Disabled) != 0) {
                    return EUserLoginResult.Disabled;
                }                

                if (item.Status == EUserStatus.NotActived) {
                    item.DateActivated = DateTime.Now;
                    UserDA.ActiveAccount(item, connectionName, null, null);

                    if (ConfigInfo.UseCache) {
                    }
                }

                item.LastLogin = DateTime.Now;
                UserDA.UpdateLastLogin(item, connectionName, null, null);

                // Update User into Cache
                if (ConfigInfo.UseCache) {
                }

                return EUserLoginResult.Success;
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.OpenIDLogin({0}): \n" + ex.ToString(), email));
                item = null;
                return EUserLoginResult.Unknown;
            }
        }

        public ECheckEmailResult CheckEmailExisted(string email) {
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                if (ConfigInfo.UseCache) {
                }
                else {
                    if (UserDA.GetByEmail(email, connectionName, null, null) == null) {
                        return ECheckEmailResult.NotExist;
                    }
                }

                return ECheckEmailResult.Exist;
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.CheckEmailExisted({0}): \n" + ex.ToString(), email));
                return ECheckEmailResult.Unknown;
            }
        }

        #endregion

        #region IUserAdmin Members

        public bool Insert(UserAdminEnt item, UserGeneralProfileEnt pItem, UserContactInfoEnt cItem) {
            UserEnt uItem = (UserEnt)item;
            return Insert(uItem, pItem, cItem);
        }

        public bool UpdateEmail(UserAdminEnt item) {
            return UpdateEmail((UserEnt)item);
        }

        public bool UpdatePassword(UserAdminEnt item) {
            return UpdatePassword((UserEnt)item);
        }

        public bool UpdateSLink(UserAdminEnt item) {
            return UpdateSLink((UserEnt)item);
        }

        public bool UpdateSLinkExpiredDate(UserAdminEnt item) {
            return UpdateSLinkExpiredDate((UserEnt)item);
        }

        public bool UpdateSLinkAndSLinkExpiredDate(UserAdminEnt item) {
            return UpdateSLinkAndSLinkExpiredDate((UserEnt)item);
        }

        public bool UpdateStatus(UserAdminEnt item) {
            return UpdateStatus((UserEnt)item);
        }

        public bool DisableUser(string userKey){
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Disabled;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.AddStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.DisableUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UnDisableUser(string userKey){
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Disabled;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;                

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.RemoveStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UnDisableUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool DeleteUser(string userKey){
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Deleted;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.AddStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.DeleteUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UnDeleteUser(string userKey){
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();
                item.Status = EUserStatus.Deleted;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.RemoveStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UnDeleteUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool VefifyUser(string userKey){
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Verified;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.AddStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.VefifyUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool UnVefifyUser(string userKey) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Verified;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.RemoveStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UnVefifyUser({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();
                    
                }
            }
            return result;
        }

        public bool Hide(string userKey) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Hidden;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.AddStatus(item, connectionName, dbCon, dbTrans) > 0;

                //Add log
                if (result) {
                }

                // Update User into Cache
                if (result && ConfigInfo.UseCache) {

                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.Hide({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();

                }
            }
            return result;
        }

        public bool UnHide(string userKey) {
            bool result = true;
            DbConnection dbCon = null;
            DbTransaction dbTrans = null;
            try {
                UserEnt item = new UserEnt();

                item.UserKey = userKey;
                item.Status = EUserStatus.Hidden;
                item.DateModified = DateTime.Now;

                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                //Create connection & transaction
                dbCon = Database.CreateConnection(connectionName, true);
                dbTrans = dbCon.BeginTransaction();

                // Update to DB
                result = UserDA.RemoveStatus(item, connectionName, dbCon, dbTrans) > 0;
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.UnHide({0}): \n" + ex.ToString(),
                                    userKey));
                result = false;
            }
            finally {
                if (dbTrans != null) {
                    if (result) {
                        dbTrans.Commit();
                    }
                    else {
                        // rollback
                        dbTrans.Rollback();
                    }
                }
                if (dbCon != null && dbCon.State == ConnectionState.Open) {
                    dbCon.Close();

                }
            }
            return result;
        }

        public UserAdminEnt GetByUserKey_Admin(string userKey) {
            UserAdminEnt item = null;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                item = UserAdminDA.GetByUserKey(userKey, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.GetByUserKey_Admin({0}): \n" + ex.ToString(), userKey));
            }
            return item;
        }

        public UserAdminEnt GetByEmail(string email) {
            UserAdminEnt item = null;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                item = UserAdminDA.GetByEmail(email, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.GetByEmail({0}): \n" + ex.ToString(), email));
            }
            return item;
        }

        public List<UserAdminEnt> GetWithConditionAndPaging(EUserGender gender, EUserStatus status, bool haveAvatar, int page, int recordPerPage, out long totalRecord) {
            List<UserAdminEnt> result = new List<UserAdminEnt>();
            totalRecord = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                totalRecord = UserAdminDA.CountWithCondition(gender, status, haveAvatar, connectionName, null, null);
                if (totalRecord == 0) {
                    return result;
                }

                int totalPage = (int)(totalRecord / recordPerPage);
                if (totalRecord % recordPerPage != 0) {
                    totalPage++;
                }
                if (page > totalPage) {
                    return result;
                }

                long startRow = (page - 1) * recordPerPage + 1;
                long endRow = startRow + recordPerPage - 1;

                if (endRow > totalRecord) {
                    endRow = totalRecord;
                }

                result = UserAdminDA.GetWithConditionAndPaging(gender, status, haveAvatar, startRow, endRow, connectionName, null, null);

            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.GetWithConditionAndPaging({0}, {1}, {2}, {3}, {4}): \n" + ex.ToString(),
                                    gender, status, haveAvatar, page, recordPerPage));
            }
            return result;
        }

        public long CountUser() {
            long result = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                result = UserDA.Count(connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error("VISS.Users.UserBC.CountUser(): \n" + ex.ToString());
                result = 0;
            }
            return result;
        }

        public long CountActivedUser() {
            long result = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                result = UserDA.CountActived(connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error("VISS.Users.UserBC.CountActivedUser(): \n" + ex.ToString());
                result = 0;
            }
            return result;
        }

        public long CountByLastLogin(DateTime startTime) {
            long result = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                result = UserDA.CountByLastLogin(startTime, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.CountByLastLogin({0}): \n" + ex.ToString(), startTime));
                result = 0;
            }
            return result;
        }


        public List<UserAdminEnt> SearchByEmail(string emailTemplate, int page, int recordPerPage, out long totalRecord) {
            List<UserAdminEnt> result = new List<UserAdminEnt>();
            totalRecord = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                totalRecord = UserAdminDA.CountSearchByEmail(emailTemplate, connectionName, null, null);
                if (totalRecord == 0) {
                    return result;
                }

                int totalPage = (int)(totalRecord / recordPerPage);
                if (totalRecord % recordPerPage != 0) {
                    totalPage++;
                }
                if (page > totalPage) {
                    return result;
                }

                long startRow = (page - 1) * recordPerPage + 1;
                long endRow = startRow + recordPerPage - 1;

                if (endRow > totalRecord) {
                    endRow = totalRecord;
                }

                result = UserAdminDA.SearchByEmailWithPaging(emailTemplate, startRow, endRow, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.SearchByEmail({0}, {1}, {2}): \n" + ex.ToString(),
                            emailTemplate,
                            page,
                            recordPerPage));
            }
            return result;
        }

        public List<UserAdminEnt> SearchByName(string nameTemplate, int page, int recordPerPage, out long totalRecord) {
            List<UserAdminEnt> result = new List<UserAdminEnt>();
            totalRecord = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                totalRecord = UserDA.Count(connectionName, null, null);
                if (totalRecord == 0) {
                    return result;
                }

                int totalPage = (int)(totalRecord / recordPerPage);
                if (totalRecord % recordPerPage != 0) {
                    totalPage++;
                }
                if (page > totalPage) {
                    return result;
                }

                long startRow = (page - 1) * recordPerPage + 1;
                long endRow = startRow + recordPerPage - 1;

                if (endRow > totalRecord) {
                    endRow = totalRecord;
                }

                //result = UserDA.GetWithPaging(startRow, endRow, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.SearchByName({0}, {1}, {2}): \n" + ex.ToString(),
                            nameTemplate,
                            page,
                            recordPerPage));
            }
            return result;
        }

        public List<UserAdminEnt> SearchByMobiPhone(string mobiPhoneTemplate, int page, int recordPerPage, out long totalRecord) {
            List<UserAdminEnt> result = new List<UserAdminEnt>();
            totalRecord = 0;
            try {
                //Get connection name
                string connectionName = ConfigInfo.ConnectionName;

                totalRecord = UserAdminDA.CountSearchByMobiPhone(mobiPhoneTemplate, connectionName, null, null);
                if (totalRecord == 0) {
                    return result;
                }

                int totalPage = (int)(totalRecord / recordPerPage);
                if (totalRecord % recordPerPage != 0) {
                    totalPage++;
                }
                if (page > totalPage) {
                    return result;
                }

                long startRow = (page - 1) * recordPerPage + 1;
                long endRow = startRow + recordPerPage - 1;

                if (endRow > totalRecord) {
                    endRow = totalRecord;
                }

                result = UserAdminDA.SearchByMobiPhoneWithPaging(mobiPhoneTemplate, startRow, endRow, connectionName, null, null);
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.SearchByMobiPhone({0}, {1}, {2}): \n" + ex.ToString(),
                            mobiPhoneTemplate,
                            page,
                            recordPerPage));
            }
            return result;
        }

        #endregion

        #region Private Methods

        private static object _lockObject = new object();
        private bool CreateUserKey(out string userKey) {

            bool result = false;
            userKey = string.Empty;

            try {
                lock (_lockObject) {
                    while (true) {
                        //Get random userkey (15 characters)
                        userKey = StringUtils.GetRandomString(15);
                        //Check if userkey exist or not
                        if (UserDA.GetByUserKey(userKey, ConfigInfo.ConnectionName, null, null) == null) {
                            result = true;
                            break;
                        }
                    }
                }
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.CreateUserKey(): \n" + ex.ToString()));
                userKey = string.Empty;
                result = false;
            }
            return result;
        }

        private bool RandomPassword(out string password) {

            bool result = false;
            password = string.Empty;

            try {
                password = StringUtils.GetRandomString(6);
                result = true;
            }
            catch (System.Exception ex) {
                LogUtils.Error(string.Format("VISS.Users.UserBC.RandomPassword(): \n" + ex.ToString()));
                password = string.Empty;
                result = false;
            }
            return result;
        }
        #endregion

        #region IUser Members

       

      

        #endregion
    }
}